class: center, middle, inverse, title-slide # R markdown for lecturing ## Ideas, tricks, and opportunities ### John Ormerod ### 24 May, 2019 --- $$ \require{color} \definecolor{prior}{RGB}{248,118,109} \definecolor{like}{RGB}{0,186,56} \definecolor{post}{RGB}{97,156,255} \definecolor{margin}{RGB}{199,124,255} $$ ### Outline * Advantages of R markdown. * Animations and gifs. * Custom colours and latex macros. * mathjax. * Opportunities. * Parting thoughts --- class: segue .white[ # R markdown ] --- ### R markdown R Markdown documents provide an interface for weaving together narrative text and code to produce elegantly formatted output using multiple languages including R, Python, and SQL. The key advantages are * Documents are fully reproducible. * Code and text are integrated into the same document. * Knitting documents to HTML allows us to leverage functionality of web browsers to create engaging and interactive content. * Animations, gifs and memes. * Interactive elements: Javascript, shiny apps, and D3. * Embedding content: YouTube, pdfs, flash and other media. --- class: segue .white[ # Animations and gifs ] --- ### Animations * Animations can be an engaging way of depicting a process in a way that would take longer if described formally as an algorithm or pseudo-code. * There are a number of packages that allow producing animations. The main packages are: * `gganimate` * `animation` * `plotly` * For each of these there is a trade-off between "easy and inflexbile" against "hard and inflexible". --- ### gganimate package .pull-left[ ```r nmax <- 30 mu <- 0 sigma <- 5 xg <- seq(-5,5,,100) dat <- c() for (n in 1:nmax) { yg <- dnorm(xg,mu,sigma/sqrt(n)) dat_bit <- cbind(xg,yg,n) dat <- rbind(dat,dat_bit) } colnames(dat) <- c("x","y","n_val") tib <- as_tibble(dat) library(gganimate) g <- ggplot(tib,aes(x=x,y=y)) + geom_line(size=1.5) + theme_bw(base_size = 22) + coord_cartesian(xlim = c(-5,5)) + labs(x='X bar',y='density', title = "n: { round(frame_time) }") + transition_time(time=n_val) ``` ] .pull-right[ <!-- --> ] --- ### animation package .small[ ```r library(animation) val <- saveGIF({ for (i in 1:nFrames) { # Plot some stuff here ani.pause() } }, movie.name="someFile.gif", img.name = "Rplot", convert = "magick", cmd.fun, clean = TRUE, extra.opts = "", interval = 0.1, nmax = 100, ani.width=1200, ani.height=600, autobrowse=FALSE, verbose=FALSE) ``` ] --- ### plotly package .pull-left[ ```r library(plotly) library(gapminder) p <- gapminder %>% plot_ly( x = ~gdpPercap, y = ~lifeExp, size = ~pop, color = ~continent, frame = ~year, text = ~country, hoverinfo = "text", type = 'scatter', mode = 'markers' ) %>% layout( xaxis = list( type = "log" ) ) ``` ] .pull-right[
Lots of examples can be found at: https://plot.ly/r/ ] --- class: segue .white[ # Examples ] --- # Sorting algorithms There are numerous sorting algorithms <center> <img src="./images/sorting.gif" style="width:75%"> </center> The "speed" of classification trees depends on how quickly one can sort. The speed of most sorting algorithms needs `\(O( n \log(n) )\)` steps to sort `\(n\)` values. --- # External link <!-- <iframe width="560" height="315" src="https://www.youtube.com/watch?v=ywWBy6J5gz8" frameborder="0" allowfullscreen></iframe> --> [For fun....](https://www.youtube.com/watch?v=ywWBy6J5gz8) --- ### Calculate the number of misclassifications along all splits for Exam1 classifying according to the majority class for the left and right splits <center> <img src="./images/two_d_cart.gif" style="width:75%"> </center> Red dots are "fails", blue dots are "passes", and crosses indicate misclassifications. --- ### Calculate the number of misclassifications along all splits for Exam2 classifying acording to the majority class for the top and bottom splits <center> <img src="./images/two_d_cart2.gif" style="width:75%"> </center> Red dots are "fails", blue dots are "passes", and crosses indicate misclassifications. --- .pull-left-2[ ### Using animations to illustrate concepts In frequentist inference estimators of parameters functions of random draws from a particular distribution, e.g., `\begin{align} \widehat{\mu} = f(X_1,\ldots,X_n) = \overline{X} \end{align}` where, say, `\begin{align} X_i \stackrel{iid}{\sim} N(\mu,\sigma^2), \qquad i=1,\ldots,n \end{align}` (with `\(\sigma^2\)` known) and `\(f(X_1,\ldots,X_n) = \frac{1}{n}\sum_{i=1}^n X_i\)`. Properties of the estimator are determined by how `\(f(X_1,\ldots,X_n)\)` behaves in expectation/variance, or as `\(n\)` becomes large. ] .pull-right-1[ <br> <br> <!-- --> ] --- ### Bayesians and Frequentists fighting And of course the main advantage of working with HTML is the memes and gifs. <center> <img src="./images/when-the-bayesians-and-frequentists-start-fighting-at-school-15489335.png" style="width:25%"> <img src="./images/fighting2.gif" style="width:25%"> <img src="./images/fighting.gif" style="width:25%"> </center> * While some might think that memes are a distraction I think this is a mistake. * People learn better when they feel psychologically safe. * Humour can "tell" the nervous system that students are safe. > Stephen W Porges (2009). > The polyvagal theory: New insights into adaptive reactions of the autonomic nervous system. > Cleveland Clinic Journal of Medicine. --- class: segue .white[ # Custom colours and latex macros ] --- .pull-left-2[ ### The rationale of Bayesian inference Bayesian inference takes in one further step. Since `\(\widehat{\mu}\)` is random why not treat `\(\mu\)` as random? The model is then treated as a conditional probability or conditional statement about the data (the `\(X_i\)`'s) conditional on the parameter(s), e.g., `\(\mu\)`. We can then state a distribution for `\(\color{prior}{p(\mu)}\)` called the .prior[prior distribution]. We Bayes theorem to derive the distribution of `\(\mu\)` conditional on the observed sample `\(x_1,\ldots,x_n\)`, i.e., `\({\color{post} p(\mu|{\bf x})}\)` called the .post[posterior distribution] `\begin{align} \displaystyle {\color{post} p(\mu|{\bf x})} = \frac{\left[ {\color{like} \prod_{i=1}^n p(x_i|\mu)} \right]{\color{prior} p(\mu)}}{\int_{-\infty}^\infty \left[ \color{like}{\prod_{i=1}^n p(x_i|\mu)} \right]{\color{prior} p(\mu)} d\mu} \end{align}` (I will explain the above in more detail later). ] .pull-right-1[ <br> <br> <!-- --> ] --- ### Custom colours and latex macros .pull-left[ * Need to download color.js from mathjax website. * In yaml header ``` includes: in_header: ["assets/mathjax-config.html"] header-includes: - \usepackage{color} ``` * In main text specify colours in RGB codes (hexadecimal not supported): ``` $$ \require{color} \definecolor{prior}{RGB}{248,118,109} \definecolor{like}{RGB}{0,186,56} \definecolor{post}{RGB}{97,156,255} \definecolor{margin}{RGB}{199,124,255} $$ ``` ] .pull-right[ * in mathjax-config.html ``` <script type="text/x-mathjax-config"> MathJax.Hub.Config({ TeX: { extensions: ["color.js"], equationNumbers: { autoNumber: "AMS" } , Macros: { bm: ["\\boldsymbol{#1}",1], y: ["y_{\\text{#1},#2}",2], yhat: ["\\hat{y}_{\\text{#1},#2}",2], ytilde: ["\\tilde{y}_{\\text{#1},#2}",2], Shat: ["\\hat{S}_{\\text{#1},#2}^{(#3)}",3], vx: ["{\\bf x}"], ds: ["\\displaystyle"] } } }); </script> ``` ] --- class: segue .white[ # mathjax ] --- ### mathjax * My biggest frustration has been typesetting equations. * Complicated equations will often compile in latex, but mathjax will not render them properly. * Some solutions: * Remove all unnecessary white spaces from equations, e.g. ``` $$P(B=b,C=c)=\sum_{k=1}^KP(B=b|A=a_k)P(C=c|A=a_k)P(A=a_k)=\sum_{k=1}^KP(A=a_k,B=b,C=c)$$ ``` `$$P(B=b,C=c)=\sum_{k=1}^KP(B=b|A=a_k)P(C=c|A=a_k)P(A=a_k)=\sum_{k=1}^KP(A=a_k,B=b,C=c)$$` ``` $$ P(B=b,C=c) = \sum_{k=1}^K P(B=b|A=a_k) P(C=c|A=a_k)P(A=a_k) = \sum_{k=1}^KP(A=a_k,B=b,C=c) $$ ``` $$ P(B=b,C=c) = \sum_{k=1}^K P(B=b|A=a_k) P(C=c|A=a_k)P(A=a_k) = \sum_{k=1}^KP(A=a_k,B=b,C=c) $$ --- ### mathjax * The align environment appears to be much more forgiving. ``` \begin{align} {\color{post}\mu|\vx} \sim N\left( w{\color{like}\overline{x}} + (1 - w){\color{prior}a}, \left(\frac{1}{\color{like}\mbox{se}^2} + \frac{1}{\color{prior}b^2}\right)^{-1} \right) \quad \mbox{where} \quad w = \frac{ \ds\frac{1}{\color{like}\mbox{se}^2} }{ \ds\frac{1}{\color{like}\mbox{se}^2} + \frac{1}{\color{prior}b^2} } \end{align} ``` `\begin{align} {\color{post}\mu|\vx} \sim N\left( w{\color{like}\overline{x}} + (1 - w){\color{prior}a}, \left(\frac{1}{\color{like}\mbox{se}^2} + \frac{1}{\color{prior}b^2}\right)^{-1} \right) \quad \mbox{where} \quad w = \frac{ \ds\frac{1}{\color{like}\mbox{se}^2} }{ \ds\frac{1}{\color{like}\mbox{se}^2} + \frac{1}{\color{prior}b^2} } \end{align}` --- class: segue .white[ # Opportunities ] --- ### A nice shiny app <br> <div style="text-align: center;"><iframe src="https://nanx.shinyapps.io/conjugate-normal-umkv/" frameborder="0" width="960" height="400"></iframe></div> <br> [Author Nan Xiao's website](https://stephens999.github.io/fiveMinuteStats/shiny_normal_example.html) <br> --- ### In class exercise Using the shiny app on the previous slide. <br> * When the prior mean is close to the data mean, what happens to the posterior distribution when * the prior standard deviation becomes small? * the prior standard deviation becomes large? * What happens to the posterior distribution when when the prior mean is far away from the data mean and * the prior standard deviation becomes small? * the prior standard deviation becomes large? --- ### `learnr` package <center> <img src="./images/learnr.png" style="width:50%"> </center> --- ### D3.js D3.js is a JavaScript library for producing dynamic, interactive data visualizations in web browsers. .pull-left[ .small[ ```r library(QUIC) library(networkD3) library(igraph) X <- na.omit(data) S <- cor(X); n <- nrow(X) res <- EBIC_QUIC(S, n, rhoMin = 0.1, rhoMax = 1, rhoN = 1000) # Get adjacency matrix and put into igraph obj. P <- res$QUIC_result$X A <- ifelse(P!=0 & row(P)!=col(P),1,0) g <- graph_from_adjacency_matrix(A, mode = "undirected", diag = FALSE) # Use community detection to find densely connected nodes wc <- cluster_walktrap(g) members <- membership(wc) # Use D3 to obtain an interactive plot of the network g_d3 <- igraph_to_networkD3(g, group = members) forceNetwork(Links = g_d3$links, Nodes = g_d3$nodes, Source = 'source', Target = 'target', NodeID = 'name', Group = 'group', linkDistance=200, charge=-10) ``` ] ] .pull-right[
] --- class: segue .white[ # Parting thoughts ] --- ### Should we be sharing teaching resources? * To quote Dan Simpson (U. Toronto): <center> <img src="./images/dan_simp70_70_70.PNG" style="width:50%"> </center> * There is too much multiple development of very similar teaching resources in statistics groups across Australia. * If we share resources, can we reduce everyone's teaching load? * DataCamp is an amazing teaching resource, but our reliance on their product in combination with mishandling of sexual misconduct has lead to many of us making awkward decisions about using their products. * Sharing teaching resources may be a solution to this problem. --- class: segue .white[ # Thank you for listening ]